<template>
	<view ref="scrollSeamless" class="scroll-seamless">
		<view
			ref="scrollPanel"
			@touchstart="stopScroll"
			@touchend="startScroll"
			class="scroll-seamless-panel"
			:style="{
				marginTop: marginTop + 'px',
				marginLeft: marginLeft + 'px',
				whiteSpace: needNowrap ? 'nowrap' : ''
			}"
		>
			<view
				ref="realRect"
				id="realRect"
				:style="{ display: needNowrap ? 'inline-block' : 'block' }"
			>
				<slot name="slot1"></slot>
			</view>
			<view
				v-if="needSlot"
				:style="{
					display: needNowrap ? 'inline-block' : 'block'
				}"
			>
				<slot name="slot2"></slot>
			</view>
		</view>
	</view>
</template>
<script>
export default {
	props: {
		options: {
			type: Object,
			default: function () {
				return {
					// up,down,left,right
					direction: 'up',
					// 滚动速度
					step: 1,
					// 触摸停止滚动
					hoverStop: true
				};
			}
		}
	},
	data() {
		return {
			// 外层容器
			seamLessRect: {},
			// 滚动面板
			scrollPanelRect: {},
			// 数据源高度
			realRect: {},
			// 滚动上边距
			marginTop: 0,
			// 滚动左边距
			marginLeft: 0,
			// 滚动定时器
			timer: null,
			// 是否追加滚动所需内容
			needSlot: true,
			// 是否需要不换行显示
			needNowrap: false
		};
	},
	beforeDestroy() {
		// 清除定时器
		if (this.timer) {
			clearInterval(this.timer);
		}
	},
	mounted() {
		this.init();
	},
	methods: {
		init() {
			this.needSlot = true;
			// #ifdef MP-WEIXIN
			uni.createSelectorQuery()
				.in(this)
				.select('.scroll-seamless')
				.boundingClientRect(function (rect) {
					this.seamLessRect = rect;
				})
				.exec();
			uni.createSelectorQuery()
				.in(this)
				.select('.scroll-seamless-panel')
				.boundingClientRect(function (rect) {
					this.scrollPanelRect = rect;
				})
				.exec();
			uni.createSelectorQuery()
				.in(this)
				.select('#realRect')
				.boundingClientRect(function (rect) {
					this.realRect = rect;
				})
				.exec();
			// #endif

			// #ifndef MP-WEIXIN
			this.seamLessRect = this.$refs['scrollSeamless'].$el.getBoundingClientRect();
			this.scrollPanelRect = this.$refs['scrollPanel'].$el.getBoundingClientRect();
			this.realRect = this.$refs['realRect']?.$el?.getBoundingClientRect();
			// #endif

			switch (this.options.direction) {
				case 'up':
					if (this.seamLessRect.height > this.realRect.height) {
						this.needSlot = false;
						return;
					}
					this.scrollUp();
					break;
				case 'down':
					if (this.seamLessRect.height > this.realRect.height) {
						this.needSlot = false;
						return;
					}
					this.marginTop = this.seamLessRect.height - this.scrollPanelRect.height;
					this.scrolldown();
					break;
				case 'left':
					this.needNowrap = true;
					setTimeout(() => {
						// #ifdef MP-WEIXIN
						const query = uni.createSelectorQuery().in(this);
						query.select('.scroll-seamless').boundingClientRect();
						query.select('.scroll-seamless-panel').boundingClientRect();
						query.select('#realRect').boundingClientRect();
						query.exec((res) => {
							// res 是一个数组，数组中包含所有选择的元素的查询结果
							// console.log('res', res)'';
							// 输出结果中包含了元素的大小和位置信息
							this.seamLessRect = res[0];
							this.scrollPanelRect = res[1];
							this.realRect = res[2];
							if (this.seamLessRect.width > this.realRect.width) {
								this.needSlot = false;
								return;
							}
							this.scrollLeft();
						});
						// #endif

						// #ifndef MP-WEIXIN
						this.seamLessRect =
							this.$refs['scrollSeamless'].$el.getBoundingClientRect();
						this.scrollPanelRect =
							this.$refs['scrollPanel'].$el.getBoundingClientRect();
						this.realRect = this.$refs['realRect']?.$el?.getBoundingClientRect();
						// console.log(this.seamLessRect.width, this.realRect.width);
						if (this.seamLessRect.width > this.realRect.width) {
							this.needSlot = false;
							return;
						}
						this.scrollLeft();
						// #endif
					}, 300);

					break;
				case 'right':
					this.needNowrap = true;
					setTimeout(() => {
						// #ifdef MP-WEIXIN
						uni.createSelectorQuery()
							.in(this)
							.select('.scroll-seamless')
							.boundingClientRect(function (rect) {
								this.seamLessRect = rect.width;
							})
							.exec();
						uni.createSelectorQuery()
							.in(this)
							.select('.scroll-seamless-panel')
							.boundingClientRect(function (rect) {
								this.scrollPanelRect = rect.width;
							})
							.exec();
						uni.createSelectorQuery()
							.in(this)
							.select('#realRect')
							.boundingClientRect(function (rect) {
								this.realRect = rect.width;
							})
							.exec();
						// #endif

						// #ifndef MP-WEIXIN
						this.seamLessRect =
							this.$refs['scrollSeamless'].$el.getBoundingClientRect();
						this.scrollPanelRect =
							this.$refs['scrollPanel'].$el.getBoundingClientRect();
						this.realRect = this.$refs['realRect']?.$el?.getBoundingClientRect();
						// #endif
						if (this.seamLessRect.width > this.realRect.width) {
							this.needSlot = false;
							return;
						}
						this.marginLeft = this.seamLessRect.width - this.realRect.width * 2;
						this.scrollRight();
					}, 0);
					break;
				default:
					if (this.seamLessRect.height > this.realRect.height) {
						this.needSlot = false;
						return;
					}
					this.scrollUp();
			}
		},
		// 向上滚动
		scrollUp() {
			this.timer = setInterval(() => {
				this.marginTop = this.marginTop - this.options.step;
				if (Math.abs(this.marginTop) >= this.realRect.height) {
					this.marginTop = 0;
				}
			}, 50);
		},
		// 向下滚动
		scrolldown() {
			this.timer = setInterval(() => {
				this.marginTop = this.marginTop + this.options.step;
				if (Math.abs(this.marginTop) <= this.realRect.height - this.seamLessRect.height) {
					this.marginTop = this.seamLessRect.height - this.scrollPanelRect.height;
				}
			}, 50);
		},
		// 向左滚动
		scrollLeft() {
			this.timer = setInterval(() => {
				this.marginLeft = this.marginLeft - this.options.step;
				// console.log(this.realRect.width, this.marginLeft, this.options.step);
				if (Math.abs(this.marginLeft) >= this.realRect.width) {
					this.marginLeft = 0;
				}
			}, 50);
		},
		// 向右滚动
		scrollRight() {
			this.timer = setInterval(() => {
				this.marginLeft = this.marginLeft + this.options.step;
				if (Math.abs(this.marginLeft) <= this.realRect.width - this.seamLessRect.width) {
					this.marginLeft = this.seamLessRect.width - this.realRect.width * 2;
				}
			}, 50);
		},
		// 停止滚动
		stopScroll() {
			// console.log('pppp', this.options.hoverStop, this.timer);
			if (this.options.hoverStop && this.timer != null) {
				// console.log('clearInterval');
				clearInterval(this.timer);
			}
		},
		// 继续滚动
		startScroll() {
			switch (this.options.direction) {
				case 'up':
					if (this.seamLessRect.height > this.realRect.height) return;
					this.scrollUp();
					break;
				case 'down':
					if (this.seamLessRect.height > this.realRect.height) return;
					this.scrolldown();
					break;
				case 'left':
					if (this.seamLessRect.width > this.realRect.width) return;
					this.scrollLeft();
					break;
				case 'right':
					if (this.seamLessRect.width > this.realRect.width) return;
					this.scrollRight();
					break;
				default:
					if (this.seamLessRect.height > this.realRect.height) return;
					this.scrollUp();
			}
		}
	}
};
</script>
<style lang="scss" scoped>
.scroll-seamless {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;

	.scroll-seamless-panel {
	}
}
</style>
